package com.config.shiro;

import org.apache.shiro.authc.credential.HashedCredentialsMatcher;
import org.apache.shiro.cache.CacheManager;
import org.apache.shiro.cache.MemoryConstrainedCacheManager;
import org.apache.shiro.mgt.SecurityManager;
import org.apache.shiro.spring.web.ShiroFilterFactoryBean;
import org.apache.shiro.spring.web.config.DefaultShiroFilterChainDefinition;
import org.apache.shiro.spring.web.config.ShiroFilterChainDefinition;
import org.apache.shiro.web.mgt.DefaultWebSecurityManager;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.PropertySource;
import org.springframework.core.env.Environment;

import javax.annotation.Resource;

@Configuration
@PropertySource(value = "classpath:shiro.properties")
public class ShiroConfigOwner {
    @Resource
    private Environment env;

    /**
     * 1.创建DBRealm对象
     * @return
     */
    @Bean
    public DBRealmOwner dbRealm(){
        DBRealmOwner realm = new DBRealmOwner();
        //将凭证匹配器加入到realm中
        realm.setCredentialsMatcher(hashedCredentialsMatcher());
        return realm;
    }

    /**
     * 2.构建Shiro的安全管理器
     * @return
     */
    @Bean
    public SecurityManager securityManager(){
        DefaultWebSecurityManager securityManager = new DefaultWebSecurityManager();
        securityManager.setRealm(dbRealm());
        securityManager.setCacheManager(cacheManager());
        return securityManager;
    }

    /**
     * 3.当Spring容器被加载成功时，自动加载安全管理器
     */
   /* @PostConstruct
    public void springInit(){
        SecurityUtils.setSecurityManager(securityManager());
    }
*/
    /**
     * 4.创建凭证匹配器
     */
    @Bean
    public HashedCredentialsMatcher hashedCredentialsMatcher(){
        HashedCredentialsMatcher matcher = new HashedCredentialsMatcher();
        matcher.setHashAlgorithmName(env.getProperty("shiro.hash.name"));//加密方式
        matcher.setHashIterations(env.getProperty("shiro.hash.count",Integer.class));
        return matcher;
    }

    /**
     * 5.将shiro过滤器和安全管理器建立联系
     * @return
     */
    @Bean(name = "shiroFilter")
    public ShiroFilterFactoryBean shiroFilterFactoryBean(){
        //1.实例化ShiroFilterFactoryBean过滤器工厂bean对象
        ShiroFilterFactoryBean factoryBean = new ShiroFilterFactoryBean();
        //2.将安全管理器设置到过滤器工厂对象中
        factoryBean.setSecurityManager(securityManager());
        //3.将过滤器规则设置到过滤器工厂对象中
        factoryBean.setFilterChainDefinitionMap(shiroFilterChainDefinition().getFilterChainMap());
        //4.重定向到登录
        factoryBean.setLoginUrl("/logins");
        return factoryBean;
    }

    /**
     * 6.定义过滤规则
     * @return
     */
    @Bean
    public ShiroFilterChainDefinition shiroFilterChainDefinition(){
        //1.实例化DefaultShiroFilterChainDefinition对象
        DefaultShiroFilterChainDefinition definition = new DefaultShiroFilterChainDefinition();
        //2.验证规则
       /* definition.addPathDefinition("/toLogin","anon");
        definition.addPathDefinition("/webjars","anon");
        definition.addPathDefinition("/logout","logout");
        definition.addPathDefinition("/**","authc");//必须登录认证后才可以访问*/
        return definition;
    }

    /**
     * 7.shiro 缓存配置
     * @return
     */
    @Bean
    public CacheManager cacheManager(){
        return new MemoryConstrainedCacheManager();
    }
}
